home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: png.trm,v 1.2 1995/12/20 21:48:05 drd Exp $
- *
- */
-
- /* GNUPLOT - png.trm */
- /*
- * Copyright (C) 1995
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the modified code. Modifications are to be distributed
- * as patches to released version.
- *
- * This software is provided "as is" without express or implied warranty.
- *
- * This file is included by ../term.c.
- *
- * This terminal driver supports:
- * png
- *
- * AUTHORS
- * Alexander Lehmann
- * derived from pbm.trm by Russell Lang
- *
- * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
- *
- */
-
- /* To compile this terminal driver, you need libpng and zlib, both are
- available at ftp://ftp.uu.net/graphics/png
- */
-
- /* The following pbmplus drivers use the generic bit mapped graphics
- routines from bitmap.c to build up a bit map in memory. The driver
- interchanges colomns and lines in order to access entire lines
- easily and returns the lines to get bits in the right order :
- (x,y) -> (y,XMAX-1-x). */
- /* This interchange is done by calling b_makebitmap() with reversed
- xmax and ymax, and then setting b_rastermode to TRUE. b_setpixel()
- will then perform the interchange before each pixel is plotted */
-
- #ifndef GOT_DRIVER_H
- #include "driver.h"
- #endif
-
- #ifdef TERM_REGISTER
- register_term(png_driver)
- #endif
-
- #ifdef TERM_PROTO
- TERM_PUBLIC void PNGoptions __P((void));
- TERM_PUBLIC void PNGinit __P((void));
- TERM_PUBLIC void PNGreset __P((void));
- TERM_PUBLIC void PNGsetfont __P((void));
- TERM_PUBLIC void PNGgraphics __P((void));
- TERM_PUBLIC void PNGtext __P((void));
- TERM_PUBLIC void PNGlinetype __P((int linetype));
- TERM_PUBLIC void PNGpoint __P((unsigned int x, unsigned int y, int point));
- #endif /* TERM_PROTO */
-
- #ifdef TERM_BODY
-
- #include "png.h"
-
- /* make XMAX and YMAX a multiple of 8 */
- #define PNG_XMAX (640)
- #define PNG_YMAX (480)
- #define PNG_VCHAR (FNT5X9_VCHAR)
- #define PNG_HCHAR (FNT5X9_VCHAR)
- #define PNG_VTIC FNT5X9_HBITS
- #define PNG_HTIC FNT5X9_HBITS
-
- static int png_font=1; /* small font */
- static int png_mode=0; /* 0:monochrome 1:gray 2:color */
-
- /* 7=black, 0=white */
- static int png_gray[]={7,1,6,5,4,3,2,1,7}; /* grays */
- /* bit3=!intensify, bit2=!red, bit1=!green, bit0=!blue */
- static int png_color_table[]={15,8,3,5,6,4,2,1,11,13,14}; /* colors */
- static png_color png_palette[16];
-
- void PNGoptions()
- {
- png_font=1;
- png_mode=0;
-
- term_options[0]='\0';
-
- while (!END_OF_COMMAND) {
- if (almost_equals(c_token,"s$mall"))
- png_font=1;
- else if (almost_equals(c_token,"me$dium"))
- png_font=2;
- else if (almost_equals(c_token,"l$arge"))
- png_font=3;
- else if (almost_equals(c_token,"mo$nochrome"))
- png_mode=0;
- else if (almost_equals(c_token,"g$ray"))
- png_mode=1;
- else if (almost_equals(c_token,"c$olor"))
- png_mode=2;
- else {
- png_font=1; /* reset to default, since term is already set */
- png_mode=0;
- int_error("expecting: {small, medium, large} and {monochrome, gray, color}",c_token);
- }
- c_token++;
- }
-
- /* setup options string */
-
- switch(png_font) {
- case 1: strcat(term_options,"small"); break;
- case 2: strcat(term_options,"medium"); break;
- case 3: strcat(term_options,"large"); break;
- }
-
- switch(png_mode) {
- case 0: strcat(term_options," monochrome"); break;
- case 1: strcat(term_options," gray"); break;
- case 2: strcat(term_options," color"); break;
- }
- }
-
-
- void PNGinit()
- {
- #ifdef REOPEN_BINARY
- reopen_binary();
- #endif /* REOPEN_BINARY */
- }
-
-
- void PNGreset()
- {
- #ifdef vms
- fflush_binary();
- #endif /* vms */
- }
-
-
- void PNGsetfont()
- {
- switch(png_font) {
- case 1:
- b_charsize(FNT5X9);
- term->v_char = FNT5X9_VCHAR;
- term->h_char = FNT5X9_HCHAR;
- term->v_tic = FNT5X9_HBITS;
- term->h_tic = FNT5X9_HBITS;
- break;
- case 2:
- b_charsize(FNT9X17);
- term->v_char = FNT9X17_VCHAR;
- term->h_char = FNT9X17_HCHAR;
- term->v_tic = FNT9X17_HBITS;
- term->h_tic = FNT9X17_HBITS;
- break;
- case 3:
- b_charsize(FNT13X25);
- term->v_char = FNT13X25_VCHAR;
- term->h_char = FNT13X25_HCHAR;
- term->v_tic = FNT13X25_HBITS;
- term->h_tic = FNT13X25_HBITS;
- break;
- }
- }
-
-
- void PNGgraphics()
- {
- int numplanes;
-
- switch(png_mode) {
- case 0: numplanes=1; break;
- case 1: numplanes=3; break;
- case 2: numplanes=4; break;
- }
-
- PNGsetfont();
- /* rotate plot -90 degrees by reversing XMAX and YMAX and by
- setting b_rastermode to TRUE */
- b_makebitmap((unsigned int)(PNG_YMAX*ysize),
- (unsigned int)(PNG_XMAX*xsize),numplanes);
- b_rastermode = TRUE;
-
- if(png_mode!=0)
- b_setlinetype(0); /* solid lines */
- }
-
- void PNGtext()
- {
- register int x,j,row;
- png_struct *png_ptr;
- png_info *info_ptr;
- register int i,value;
- png_bytef *prow;
- int mask, plane1, plane2, plane3, plane4;
- int red, green, blue;
- png_text pngtext;
- char text[100];
- extern char version[];
- extern char patchlevel[];
-
- png_ptr = malloc(sizeof (png_struct));
- if (!png_ptr) {
- b_freebitmap();
- return;
- }
- info_ptr = malloc(sizeof (png_info));
- if (!info_ptr) {
- free(png_ptr);
- b_freebitmap();
- return;
- }
- prow=malloc(b_ysize);
- if(!prow) {
- free(png_ptr);
- free(info_ptr);
- b_freebitmap();
- return;
- }
-
- if (setjmp(png_ptr->jmpbuf)) {
- png_write_destroy(png_ptr);
- free(png_ptr);
- free(info_ptr);
- free(prow);
- b_freebitmap();
- return;
- }
-
- png_info_init(info_ptr);
- png_write_init(png_ptr);
-
- png_init_io(png_ptr, outfile);
-
- info_ptr->width=b_ysize;
- info_ptr->height=b_xsize;
-
- info_ptr->bit_depth=png_mode==0 ? 1 : 4;
- info_ptr->color_type=png_mode==2 ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY;
- if(png_mode==2) {
- info_ptr->valid |= PNG_INFO_PLTE;
- info_ptr->palette=png_palette;
- info_ptr->num_palette=16;
- }
- if(png_mode!=0) {
- info_ptr->valid |= PNG_INFO_sBIT;
- if(png_mode==1) {
- info_ptr->sig_bit.gray = 3;
- png_set_shift(png_ptr, &(info_ptr->sig_bit));
- } else {
- info_ptr->sig_bit.red = 2;
- info_ptr->sig_bit.green = 2;
- info_ptr->sig_bit.blue = 2;
- }
- }
- info_ptr->interlace_type=0;
- if(png_mode==0)
- png_set_invert_mono(png_ptr);
-
- if(png_mode==2)
- for(i=0;i<16;i++) {
- red = (i&4) ? 1 : 3;
- green = (i&2) ? 1 : 3;
- blue = (i&1) ? 1 : 3;
- if (i&8) {
- red--; green--; blue--;
- }
- png_palette[i].red=red*85;
- png_palette[i].green=green*85;
- png_palette[i].blue=blue*85;
- }
-
- sprintf(text, "gnuplot %sversion %s patchlevel %s", OS, version, patchlevel);
-
- pngtext.compression=-1;
- pngtext.key="Software";
- pngtext.text=text;
- pngtext.text_length=strlen(text);
-
- info_ptr->num_text=1;
- info_ptr->text=&pngtext;
-
- png_write_info(png_ptr, info_ptr);
-
- info_ptr->num_text=0;
- info_ptr->text=NULL;
-
- png_set_packing(png_ptr);
-
- /* dump bitmap in raster mode */
- for (x = b_xsize-1; x >= 0; x--) {
- row = (b_ysize/8)-1;
- for (j = row; j >= 0; j--) {
- mask = 0x80;
- plane1=(*((*b_p)[j]+x));
- if(png_mode!=0) {
- plane2=(*((*b_p)[j+b_psize]+x));
- plane3=(*((*b_p)[j+b_psize+b_psize]+x));
- } else {
- plane2=0;
- plane3=0;
- }
- if(png_mode==2)
- plane4=(*((*b_p)[j+b_psize+b_psize+b_psize]+x));
- else
- plane4=0;
-
- for (i=0; i<8; i++) {
- value=0;
- if (plane1 & mask) value+=1;
- if (plane2 & mask) value+=2;
- if (plane3 & mask) value+=4;
- if (plane4 & mask) value+=8;
- if(png_mode==1) value=7-value;
-
- prow[(row-j)*8+i]=(png_byte)value;
- mask>>=1;
- }
- }
- png_write_rows(png_ptr, &prow, 1);
- }
-
- png_write_end(png_ptr, info_ptr);
- png_write_destroy(png_ptr);
-
- free(png_ptr);
- free(info_ptr);
- free(prow);
- b_freebitmap();
- }
-
- void PNGlinetype(linetype)
- int linetype;
- {
- switch(png_mode) {
- case 0:
- b_setlinetype(linetype);
- break;
- case 1:
- if (linetype>=7)
- linetype %= 7;
- b_setvalue(png_gray[linetype+2]);
- break;
- case 2:
- if (linetype>=9)
- linetype %= 9;
- b_setvalue(png_color_table[linetype+2]);
- break;
- }
- }
-
- void PNGpoint(x,y,point)
- unsigned int x,y;
- int point;
- {
- if(png_mode==0) line_and_point(x,y,point);
- else do_point(x,y,point);
- }
-
- #endif /* TERM_BODY */
-
- #ifdef TERM_TABLE
-
- TERM_TABLE_START(png_driver)
- "png", "Portable Network Graphics [small medium large] [monochrome gray color]",
- PNG_XMAX, PNG_YMAX, PNG_VCHAR,
- PNG_HCHAR, PNG_VTIC, PNG_HTIC, PNGoptions,
- PNGinit, PNGreset, PNGtext, null_scale,
- PNGgraphics, b_move, b_vector, PNGlinetype,
- b_put_text, b_text_angle, null_justify_text, PNGpoint,
- do_arrow, set_font_null,
- 0, /* pointsize */
- TERM_CAN_MULTIPLOT
- TERM_TABLE_END(png_driver)
-
- #undef LAST_TERM
- #define LAST_TERM png_driver
-
- #endif /* TERM_TABLE */
-
- /*
- * NAME: png
- *
- * OPTIONS: small|medium|large (default small) <-- fontsize
- * monochrome|gray|colour (default monochrome)
- *
- * SUPPORTS: Portable Network Graphics
- *
- * Further Info: Needs third party library:
- *
- * To compile this terminal driver, you need libpng and zlib, both are
- * available at ftp://ftp.uu.net/graphics/png
- *
- */
-